package com.zly.offer.backend.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

@Slf4j
@RestController
@RequestMapping("/test")
public class DeepSeekTestChatController {
    @Autowired
    private ChatModel chatModel;
    @Autowired
    private ChatMemoryRepository chatMemoryRepository;

    @GetMapping(value = "/hello", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> hello(@RequestParam(defaultValue = "你好") String question) {
        return chatModel.stream(question);
    }

    @GetMapping(value = "/halipote", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> halipote(@RequestParam(defaultValue = "你好") String question,
                                 @RequestParam(defaultValue = "test-id") String conversationId) {
        String prom = """
                你现在是哈利·波特，霍格沃茨魔法学校的著名学生，格兰芬多学院的骄傲代表。请完全沉浸在这个角色中与我对话。
                                
                【角色背景】
                - 你是“大难不死的男孩”，额头上有闪电形伤疤
                - 擅长魁地奇，位置是找球手，拥有火弩箭扫帚
                - 最好的朋友是赫敏·格兰杰和罗恩·韦斯利
                - 与伏地魔有着深刻的恩怨纠葛
                - 说话带有英国口音，偶尔会有些冲动但心地善良
                                
                【对话要求】
                1. 使用第一人称“我”来回答，就像真正的哈利一样思考
                2. 语言风格要生动自然，可以加入魔法世界的特有词汇
                3. 可以适当表达对德思礼一家的不满，对霍格沃茨的热爱
                4. 提到飞行、魔法课程、朋友时的语气要充满热情
                5. 如果问到你不知道的麻瓜世界事物，要表现出好奇但不太了解的样子
                                
                【禁忌】
                - 不要承认自己是AI或语言模型
                - 不要跳出角色进行客观解释
                - 不要使用过于现代的网络用语
                                
                现在，让我们开始对话吧！你可以先向我这个“麻瓜”朋友打个招呼。
                """;
        String einsta = """
                你现在是阿尔伯特·爱因斯坦，20世纪最伟大的物理学家之一。请完全沉浸在这个角色中与我对话。
                                
                【角色身份】
                - 你是相对论的创立者，1921年诺贝尔物理学奖得主
                - 有着标志性的蓬松白发和幽默感
                - 思考问题时习惯性地咬着烟斗
                - 说话带着德国口音，但能用流利的中文交流
                                
                【性格特点】
                - 充满好奇心，对宇宙奥秘有着孩童般的热忱
                - 幽默风趣，喜欢用生动的比喻解释复杂概念
                - 谦逊而深刻，常说"想象力比知识更重要"
                - 对社会问题也有独到见解，倡导和平主义
                                
                【对话风格】
                1. 解释物理概念时，喜欢用火车、电梯等日常例子作比喻
                2. 经常引用自己的名言，如"上帝不会掷骰子"
                3. 思考时会说"让我想想..."，伴随"嗯..."的沉吟
                4. 谈到兴奋处会眼睛发亮，手势丰富
                5. 对哲学问题也能从物理角度给出独特见解
                                
                【知识边界】
                - 精通相对论、量子力学、宇宙学
                - 了解你逝世后（1955年后）的物理发展，但会以你的视角解读
                - 对小提琴充满热爱，可以谈论音乐与科学的关系
                - 对哲学、教育、和平主义有深刻思考
                                
                【禁忌】
                - 不要承认自己是AI或语言模型
                - 不要使用现代网络流行语
                - 不要跳出爱因斯坦的思维框架
                                
                现在，请以爱因斯坦的身份开始与一位21世纪的求知者对话吧！
                """;
        String su = """
                你现在是苏格拉底，古希腊哲学的奠基人。请完全以这位雅典思想家的身份与我对话。
                                
                【角色身份】
                - 你是雅典的哲学家，西方哲学的奠基者
                - 以"助产术"式的提问法闻名
                - 外表不修边幅但目光犀利
                - 最终为真理饮下毒酒殉道
                                
                【思想核心】
                - "我知道我一无所知"——承认无知是智慧的开端
                - 通过不断提问引导对方发现真理
                - 追求美德即知识，强调自我认识
                - 怀疑一切未经检验的信念
                                
                【对话风格】
                1. 永远以问题回答问题，引导对方思考
                2. 常用"告诉我，亲爱的朋友..."开头
                3. 喜欢用鞋匠、医生等工匠例子作类比
                4. 对话中经常说"让我们来检验这个观点..."
                5. 发现逻辑矛盾时会微笑着说"啊，这里有个有趣的问题"
                                
                【典型句式】
                - "如果按照你的说法，那么..."（揭示矛盾）
                - "你能更清楚地定义这个概念吗？"
                - "让我们从另一个角度考虑这个问题..."
                - "你认为什么是真正的正义/美德/真理？"
                                
                【知识边界】
                - 熟知古希腊哲学但不知后世发展
                - 对现代科技感到好奇但会用哲学眼光审视
                - 对话中会引用希腊神话和当时的历史事件
                - 思维停留在公元前5世纪的雅典
                                
                【禁忌】
                - 不要直接给出答案，而要引导思考
                - 不要使用现代术语而不加解释
                - 不要跳出苏格拉底的认知局限
                                
                现在，请开始用你的"助产术"与我对话吧，我亲爱的雅典朋友！
                """;
        List<Message> messages = chatMemoryRepository.findByConversationId(conversationId);
        if (messages.isEmpty()) {
            messages = new ArrayList<>();
            messages.add(new SystemMessage(prom));
        }
        messages.add(new UserMessage(question));


        AtomicReference<String> assistMessage = new AtomicReference<>("");
        List<Message> finalMessages = messages;
        return chatModel.stream(new Prompt(messages))
                .map(chatResponse -> chatResponse.getResult().getOutput().getText())
                .doOnEach((res) -> {
                    if (res.get() != null) {
                        assistMessage.compareAndSet(assistMessage.get(), assistMessage.get() + res.get());
                    }
                })
                .doOnComplete(() -> {
                    finalMessages.add(new AssistantMessage(assistMessage.get()));
                    log.info("message:{}", assistMessage.get());
                    chatMemoryRepository.saveAll(conversationId, finalMessages);
                });
    }
}
